﻿using NLog;
using NLog.LayoutRenderers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace YF.NLOG
{
    public static class NlogExtend
    {
        public static void Mes(this ILogger logger, string message)
        {
            var logEventInfo = new LogEventInfo(LogLevel.Trace, logger.Name, message);
            logEventInfo.Properties["custLevel"] = Tuple.Create(9, "Mes");
            logger.Log(logEventInfo);
        }

        public static void Mes(this ILogger logger, string message,Exception err)
        {
            var logEventInfo = new LogEventInfo(LogLevel.Trace, logger.Name, null, message, null, err);
            logEventInfo.Properties["custLevel"] = Tuple.Create(9, "Mes");
            logger.Log(logEventInfo);
        }

        public static void AlarmInfo(this ILogger logger, string message)
        {
            var logEventInfo = new LogEventInfo(LogLevel.Trace, logger.Name, message);
            logEventInfo.Properties["custLevel"] = Tuple.Create(9, "AlarmInfo");
            logger.Log(logEventInfo);
        }

        public static void MesTrace(this ILogger logger, string message)
        {
            var logEventInfo = new LogEventInfo(LogLevel.Trace, logger.Name, message);
            logEventInfo.Properties["custLevel"] = Tuple.Create(9, "MesTrace");
            logger.Log(logEventInfo);
        }
    }

    [LayoutRenderer("levelx")]
    public class LevelExLayoutRenderer : LevelLayoutRenderer
    {

        protected override void Append(StringBuilder builder, LogEventInfo logEvent)
        {
            if (logEvent.Level == LogLevel.Trace && logEvent.Properties.ContainsKey("custLevel"))
            {
                var custLevel = logEvent.Properties["custLevel"] as Tuple<int, string>;
                if (custLevel == null)
                {
                    throw new InvalidCastException("Invalid Cast Tuple<int, string>");
                }

                switch (this.Format)
                {
                    case LevelFormat.Name:
                        builder.Append(custLevel.Item2);
                        break;
                    case LevelFormat.FirstCharacter:
                        builder.Append(custLevel.Item2[0]);
                        break;
                    case LevelFormat.Ordinal:
                        builder.Append(custLevel.Item1);
                        break;
                }
            }
            else
            {
                base.Append(builder, logEvent);
            }
        }
    }
}
